﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Common;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using WqLunTan.Areas.Manage.Models;
using WqLunTan.Filters;
using WqLunTan.Models.DataBase;
using WqLunTan.Models.ViewModel;

namespace WqLunTan.Controllers
{
    /// <summary>
    /// 用户帖子内容控制器
    /// </summary>
    public class PostController : BaseController
    {
        /// <summary>
        /// 添加
        /// </summary>
        /// <returns></returns>
        [Auth(AuthType = WqUserAuth.User)]
        public IActionResult Add()
        {
            return View();
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        [Auth(AuthType = WqUserAuth.User)]
        public IActionResult Save(string title, string content)
        {
            if (!string.IsNullOrWhiteSpace(title) && !string.IsNullOrWhiteSpace(content))
            {
                var postTitle = new post_title();
                postTitle.title = title;
                postTitle.create_time = DateTimeOffset.UtcNow;
                postTitle.is_show = true;
                postTitle.keywords = title;
                postTitle.sort_num = 100;
                postTitle.top = false;
                postTitle.uid = LoginUser.Id;
                postTitle.last_update = DateTimeOffset.UtcNow;

                try
                {
                    DbContext.Database.BeginTransaction();
                    DbContext.PostTitle.Add(postTitle);
                    DbContext.SaveChanges();

                    var postContent = new post_content();
                    postContent.content = content;
                    postContent.create_time = DateTimeOffset.UtcNow;
                    postContent.is_show = true;
                    postContent.last_update = DateTimeOffset.UtcNow;
                    postContent.tid = postTitle.id;
                    postContent.uid = LoginUser.Id;
                    postContent.uname = LoginUser.NickName;

                    DbContext.PostContent.Add(postContent);
                    DbContext.SaveChanges();

                    DbContext.Database.CommitTransaction();
                    httpCacheHelper.RemoveCacheByKey("post_list_layout");
                }
                catch (Exception ex)
                {
                    DbContext.Database.RollbackTransaction();
                    Logger.LogError(ex, ex.Message);
                }
            }
            return JsonOkResult("保存成功");
        }

        /// <summary>
        /// 帖子列表
        /// </summary>
        /// <param name="search"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IActionResult List(string search, int pageIndex = 1, int pageSize = 20)
        {
            List<TitleUserExt> list = null;
            var page = new PageModel() { CurrentPageIndex = pageIndex };
            var query = from t in DbContext.PostTitle
                        join u in DbContext.Users on t.uid equals u.Id
                        where t.is_show == true
                        orderby t.top descending, t.sort_num ascending, t.create_time descending
                        select new TitleUserExt()
                        {
                            id = t.id,
                            create_time = t.create_time,
                            title = t.title,
                            keywords = t.keywords,
                            nick_name = u.NickName,
                            sort_num = t.sort_num,
                            is_show = t.is_show,
                            top = t.top,
                            uid = t.uid
                        };

            if (string.IsNullOrWhiteSpace(search))
            {
                var key = $"post-list-{pageIndex}-{pageSize}";
                var pageKey = $"post-list-{pageIndex}-{pageSize}-page";
                list = httpCacheHelper.getCache<List<TitleUserExt>>(key);
                if (list != null && list.Count > 0)
                {
                    page = httpCacheHelper.getCache<PageModel>(pageKey);
                }
                else
                {
                    page.TotalCount = query.Count();
                    list = query.Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
                    httpCacheHelper.setCache(key, list, 1);
                    httpCacheHelper.setCache(pageKey, page, 1);
                }
            }
            else
            {
                query = query.Where(x => x.title.Contains(search) || x.keywords.Contains(search));
                page.TotalCount = query.Count();
                list = query.Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
            }

            ViewData["list"] = list;
            ViewData["page"] = page;

            return View();
        }

        /// <summary>
        /// 贴子详情页
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IActionResult Detail(Guid id, int pageIndex = 1, int pageSize = 20)
        {
            var key = $"post-detail-{id.ToString("N")}-{pageIndex}-{pageSize}";
            var keyContent = $"post-detail-content-{id.ToString("N")}-{pageIndex}-{pageSize}";
            var keyReply = $"post-detail-reply-{id.ToString("N")}-{pageIndex}-{pageSize}";
            var pageKey = $"post-detail-page-{id.ToString("N")}-{pageIndex}-{pageSize}";

            var page = new PageModel() { CurrentPageIndex = pageIndex };
            var postTitle = httpCacheHelper.getCache<post_title>(key);
            var isUpdate = httpCacheHelper.getCache<bool>($"post-detail-update-{id.ToString("N")}");
            if (postTitle == null || isUpdate)
            {
                postTitle = DbContext.PostTitle.Where(x => x.id == id && x.is_show).SingleOrDefault();
                if (postTitle != null)
                {
                    var query = DbContext.PostContent.Where(x => x.tid == postTitle.id && x.is_show);
                    page.TotalCount = query.Count();
                    var postContent = query.OrderBy(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
                    var postReply = DbContext.PostReply.Where(x => x.post_tid == postTitle.id && x.is_show).OrderBy(x => x.create_time).Skip(pageSize * pageIndex - pageSize).Take(pageSize).ToList();
                    httpCacheHelper.setCache(key, postTitle, 1);
                    httpCacheHelper.setCache(keyContent, postContent, 2);
                    httpCacheHelper.setCache(keyReply, postReply, 2);
                    httpCacheHelper.setCache(pageKey, page, 2);
                }
                else
                {
                    return NotFound();
                }
            }
            ViewData["postTitle"] = postTitle;
            ViewData["content"] = httpCacheHelper.getCache<List<post_content>>(keyContent) ?? new List<post_content>();
            ViewData["reply"] = httpCacheHelper.getCache<List<post_reply>>(keyReply) ?? new List<post_reply>();
            ViewData["page"] = httpCacheHelper.getCache<PageModel>(pageKey) ?? new PageModel();

            return View();
        }

        /// <summary>
        /// 回复贴子内容
        /// </summary>
        /// <param name="cid"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [Auth(AuthType = WqUserAuth.User)]
        public IActionResult PostReply(Guid cid, string content)
        {
            if (!string.IsNullOrWhiteSpace(content))
            {
                var postContent = DbContext.PostContent.Where(x => x.is_show && x.id == cid).SingleOrDefault();
                if (postContent != null)
                {
                    var reply = new post_reply()
                    {
                        uid = LoginUser.Id,
                        post_cid = postContent.id,
                        post_tid = postContent.tid,
                        content = content,
                        is_show = true,
                        uname = LoginUser.NickName,
                        create_time = DateTimeOffset.UtcNow,
                        last_update = DateTimeOffset.UtcNow
                    };
                    DbContext.PostReply.Add(reply);
                    DbContext.SaveChanges();
                    httpCacheHelper.setCache($"post-detail-update-{postContent.tid.ToString("N")}", true, 1);
                }
            }
            return JsonOkResult("保存成功");
        }

        /// <summary>
        /// 举报
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Auth(AuthType = WqUserAuth.User)]
        public IActionResult PostInform(Guid id)
        {
            var postContent = DbContext.PostContent.Where(x => x.is_show && x.id == id).SingleOrDefault();
            if (postContent != null)
            {
                var inform = new post_inform()
                {
                    tid = postContent.tid,
                    cid = postContent.id,
                    ip = UserIPAddress,
                    reason = string.Empty,
                    state = PostInformState.Init,
                    addtime = DateTimeOffset.UtcNow
                };
                DbContext.PostInform.Add(inform);
                DbContext.SaveChanges();
            }
            return JsonOkResult("举报成功");
        }

        /// <summary>
        /// 回贴
        /// </summary>
        /// <param name="tid"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        [Auth(AuthType = WqUserAuth.User)]
        public IActionResult ReplyPost(Guid tid, string content)
        {
            if (!string.IsNullOrWhiteSpace(content))
            {
                var postTitle = DbContext.PostTitle.Where(x => x.id == tid && x.is_show).SingleOrDefault();
                if (postTitle != null)
                {
                    var postContent = new post_content()
                    {
                        content = content,
                        create_time = DateTimeOffset.UtcNow,
                        is_show = true,
                        last_update = DateTimeOffset.UtcNow,
                        tid = tid,
                        uid = LoginUser.Id,
                        uname = LoginUser.NickName
                    };
                    DbContext.PostContent.Add(postContent);
                    DbContext.SaveChanges();
                    httpCacheHelper.setCache($"post-detail-update-{tid.ToString("N")}", true, 1);
                }
            }
            return JsonOkResult("保存成功");
        }
    }
}